
package com.tendory.gpssim.activity;

import android.Manifest;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.TwoStatePreference;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;

import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import com.alibaba.android.arouter.launcher.ARouter;
import com.tendory.common.base.RxBus;
import com.tendory.common.per.PermissionsCallbacks;
import com.tendory.common.per.ZPermissions;
import com.tendory.gpssim.BuildConfig;
import com.tendory.gpssim.R;
import com.tendory.gpssim.evt.EvtIpConnected;
import com.tendory.gpssim.evt.EvtLocationError;
import com.tendory.gpssim.evt.EvtStartPos;
import com.tendory.gpssim.evt.EvtStopPos;
import com.tendory.gpssim.service.TrackingService;
import com.tendory.gpssim.receiver.AutostartReceiver;
import com.trello.rxlifecycle3.components.RxPreferenceFragment;

import org.greenrobot.eventbus.EventBus;

import java.util.List;

public class MainFragment extends RxPreferenceFragment implements OnSharedPreferenceChangeListener {

    private static final String TAG = MainFragment.class.getSimpleName();

    private static final int ALARM_MANAGER_INTERVAL = 15000;

    public static final String KEY_DEVICE = "id";
    public static final String KEY_URL = "url";
    public static final String KEY_ENABLE_POS = "enable_pos";
    public static final String KEY_INTERVAL = "interval";
    public static final String KEY_DISTANCE = "distance";
    public static final String KEY_ANGLE = "angle";
    public static final String KEY_ACCURACY = "accuracy";
    public static final String KEY_STATUS = "status";
    public static final String KEY_BUFFER = "buffer";

    private static final int PERMISSIONS_REQUEST_LOCATION = 2;

    private SharedPreferences sharedPreferences;

    private AlarmManager alarmManager;
    private PendingIntent alarmIntent;

    private final CompositeDisposable disposables = new CompositeDisposable();
    public void addSubscription(Disposable s) {
        disposables.add(s);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        disposables.clear();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (BuildConfig.HIDDEN_APP) {
            removeLauncherIcon();
        }

        setHasOptionsMenu(true);

        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        addPreferencesFromResource(R.xml.preferences);
        initPreferences();

        findPreference(KEY_DEVICE).setOnPreferenceChangeListener((preference, newValue) -> newValue != null && !newValue.equals(""));
        findPreference(KEY_URL).setOnPreferenceChangeListener((preference, newValue) -> (newValue != null) && validateServerURL(newValue.toString()));

        findPreference(KEY_INTERVAL).setOnPreferenceChangeListener((preference, newValue) -> {
            if (newValue != null) {
                try {
                    int value = Integer.parseInt((String) newValue);
                    return value > 0;
                } catch (NumberFormatException e) {
                    Log.w(TAG, e);
                }
            }
            return false;
        });

        Preference.OnPreferenceChangeListener numberValidationListener = (preference, newValue) -> {
            if (newValue != null) {
                try {
                    int value = Integer.parseInt((String) newValue);
                    return value >= 0;
                } catch (NumberFormatException e) {
                    Log.w(TAG, e);
                }
            }
            return false;
        };
        findPreference(KEY_DISTANCE).setOnPreferenceChangeListener(numberValidationListener);
        findPreference(KEY_ANGLE).setOnPreferenceChangeListener(numberValidationListener);

        alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
        alarmIntent = PendingIntent.getBroadcast(getActivity(), 0, new Intent(getActivity(), AutostartReceiver.class), 0);

        addSubscription(RxBus.getInstance().toObserverable(EvtIpConnected.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::stopWaitingDialog, Throwable::printStackTrace));
        addSubscription(RxBus.getInstance().toObserverable(EvtLocationError.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::locationError, Throwable::printStackTrace));

        if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
            startTrackingService();
        }
//        setDialog();
        //悬浮窗权限判断
//        if (Build.VERSION.SDK_INT >= 23) {
//            if (!Settings.canDrawOverlays(getActivity().getApplicationContext())) {
//                //启动Activity让用户授权
//                setFloatWindowDialog();
//            }
//        }
    }

    private void locationError(EvtLocationError evt) {
//        stopTrackingService();
//        closeMonitor();
        sharedPreferences.edit().putBoolean(KEY_ENABLE_POS, false).apply();
    }

    private void removeLauncherIcon() {
        String className = MainActivity.class.getCanonicalName().replace(".MainActivity", ".Launcher");
        ComponentName componentName = new ComponentName(getActivity().getPackageName(), className);
        PackageManager packageManager = getActivity().getPackageManager();
        if (packageManager.getComponentEnabledSetting(componentName) != PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
            packageManager.setComponentEnabledSetting(
                    componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);

            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder.setMessage(getString(R.string.hidden_alert));
            builder.setPositiveButton(android.R.string.ok, null);
            builder.show();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        sharedPreferences.registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
    }

    private void setPreferencesEnabled(boolean enabled) {
        findPreference(KEY_DEVICE).setEnabled(enabled);
        findPreference(KEY_URL).setEnabled(enabled);
        findPreference(KEY_INTERVAL).setEnabled(enabled);
        findPreference(KEY_DISTANCE).setEnabled(enabled);
        findPreference(KEY_ANGLE).setEnabled(enabled);
        findPreference(KEY_ACCURACY).setEnabled(enabled);
        findPreference(KEY_BUFFER).setEnabled(enabled);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if (key.equals(KEY_STATUS)) {
            if (sharedPreferences.getBoolean(KEY_STATUS, false)) {
                startTrackingService();
            } else {
                stopTrackingService();
            }
        } else if (key.equals(KEY_ENABLE_POS)) {
            if (sharedPreferences.getBoolean(KEY_ENABLE_POS, false)) {
                startPos();
            } else {
                stopPos();
            }
        } else if (key.equals(KEY_DEVICE)) {
            findPreference(KEY_DEVICE).setSummary(sharedPreferences.getString(KEY_DEVICE, null));
        }
    }

    private void startPos() {
        EventBus.getDefault().post(new EvtStartPos());
    }

    private void stopPos() {
        EventBus.getDefault().post(new EvtStopPos());
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.main, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.status) {
            startActivity(new Intent(getActivity(), StatusActivity.class));
            return true;
        } else if (item.getItemId() == R.id.map) {
            ARouter.getInstance().build("/map/main")
//                    .withBoolean("isAManager", true)
                    .navigation();
        } else if (item.getItemId() == R.id.about) {
            startActivity(new Intent(getActivity(), AboutActivity.class));
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void initPreferences() {
        PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);

        if (!sharedPreferences.contains(KEY_DEVICE)) {
            String id = "13600100345";
            sharedPreferences.edit().putString(KEY_DEVICE, id).apply();
            ((EditTextPreference) findPreference(KEY_DEVICE)).setText(id);
        }
        findPreference(KEY_DEVICE).setSummary(sharedPreferences.getString(KEY_DEVICE, null));
    }

    private void startTrackingService() {
        ZPermissions.with(this).permission(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
        )
                .setPermissionsCallbacks(new PermissionsCallbacks() {
                    @Override
                    public void onPermissionsGranted(int requestCode, List<String> perms) {
                        setPreferencesEnabled(false);
                        ContextCompat.startForegroundService(getActivity(), new Intent(getActivity(), TrackingService.class));
                        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                                ALARM_MANAGER_INTERVAL, ALARM_MANAGER_INTERVAL, alarmIntent);
//                        startWaitingDialog();
                    }

                    @Override
                    public void onPermissionsDenied(int requestCode, List<String> perms) {
                        closeMonitor();
                    }
                }).request();
    }

    private void closeMonitor() {
        sharedPreferences.edit().putBoolean(KEY_STATUS, false).apply();
        TwoStatePreference preference = (TwoStatePreference) findPreference(KEY_STATUS);
        preference.setChecked(false);
    }

    private ProgressDialog progressDialog;
    private void startWaitingDialog() {
        progressDialog = new ProgressDialog(getActivity());
        progressDialog.setIndeterminate(false);//循环滚动
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progressDialog.setMessage("连接中...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }
    private void stopWaitingDialog(EvtIpConnected evt) {
        if (progressDialog != null) {
            progressDialog.dismiss();
            progressDialog = null;
        }
        if (!evt.isConnected()) {
            closeMonitor();
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("连接失败");
            builder.setMessage("连接失败");
            builder.setPositiveButton("确定", null);
            builder.show();
        }
    }

    private void stopTrackingService() {
        alarmManager.cancel(alarmIntent);
        getActivity().stopService(new Intent(getActivity(), TrackingService.class));
        setPreferencesEnabled(true);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        ZPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    private boolean validateServerURL(String userUrl) {
        String[] us = userUrl.split(":");
        if (us.length == 2) {
            try {
                int port = Integer.parseInt(us[1]);
                if (port == -1 || (port > 0 && port <= 65535)) {
                    return true;
                }
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        Toast.makeText(getActivity(), R.string.error_msg_invalid_url, Toast.LENGTH_LONG).show();
        return false;
    }

    //提醒开启位置模拟的弹框
    private void setDialog() {
        //判断是否开启开发者选项
//        boolean enableAdb = (Settings.Secure.getInt(getContentResolver(), Settings.Secure.ALLOW_MOCK_LOCATION, 0) > 0);
//        if (!enableAdb) {
//            DisplayToast("请打先开开发者选项");
//            return;
//        }
        new AlertDialog.Builder(getActivity())
                .setTitle("启用位置模拟")//这里是表头的内容
                .setMessage("请在\"开发者选项→选择模拟位置信息应用\"中进行设置")//这里是中间显示的具体信息
                .setPositiveButton("设置",//这个string是设置左边按钮的文字
                        (dialog, which) -> {
                            try {
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS);
                                startActivity(intent);
                            } catch (Exception e) {
//                                DisplayToast("无法跳转到开发者选项,请先确保您的设备已处于开发者模式");
                                e.printStackTrace();
                            }
                        })//setPositiveButton里面的onClick执行的是左边按钮
                .setNegativeButton("取消",//这个string是设置右边按钮的文字
                        null)//setNegativeButton里面的onClick执行的是右边的按钮的操作
                .show();
    }
    //提醒开启悬浮窗的弹框
    private void setFloatWindowDialog() {
        new AlertDialog.Builder(getActivity())
                .setTitle("启用悬浮窗")//这里是表头的内容
                .setMessage("为了模拟定位的稳定性，建议开启\"显示悬浮窗\"选项")//这里是中间显示的具体信息
                .setPositiveButton("设置",//这个string是设置左边按钮的文字
                        (dialog, which) -> {
                            try {
                                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getActivity().getPackageName()));
                                startActivity(intent);
                            } catch (Exception e) {
//                                DisplayToast("无法跳转到设置界面，请在权限管理中开启该应用的悬浮窗");
                                e.printStackTrace();
                            }
                        })//setPositiveButton里面的onClick执行的是左边按钮
                .setNegativeButton("取消",//这个string是设置右边按钮的文字
                        null)//setNegativeButton里面的onClick执行的是右边的按钮的操作
                .show();
    }

}
